#include <iostream>
#include <fstream>
#include "common.h"
#include "Sphere.h"
#include "hittable.h"
#include "hittable_list.h"
// #include "color.h"
// #include "ray.h"
// #include "vec3.h"


color ray_color(const ray& r, hittable& world){
    hit_record rec;
    // 计算射线与物体的交点
    if( world.hit(r,0,infinity,rec)){
        return 0.5 * (rec.normal + color(1,1,1));
    }
       
    
    
    // 计算射线的方向向量
    vec3 unit_direction = unit_vector(r.direction());
    // 计算归一化后的y值
    auto  t  = 0.5 *(unit_direction.y() + 1.0);// 归一化
    // 返回颜色
    return (1.0 - t)*color(1.,1.,1.) + t* color(0.5, 0.7, 1.0);//mix

}

int main(){
    auto aspect_ratio  = 16.0/9.0;
    int image_width = 400;
    // calculate the image height, and ensure that it's at least 1.
    int image_height = int(image_width/aspect_ratio);
    image_height = (image_height >1)?image_height:1;

    hittable_list world;
    world.add(make_shared<sphere>(point3(0,0,-1),0.5));
    world.add(make_shared<sphere>(point3(0,-100.5,-1),100));

    // camera
    auto focal_legth =1.0;
    auto viewport_height= 2.0;
    auto viewport_width = viewport_height *(double(image_width)/image_height);
    auto camera_center = point3(0,0,0);

    auto viewport_u= vec3(viewport_width,0,0);
    auto viewport_v= vec3(0,-viewport_height,0);
    
    auto pixel_delta_u= viewport_u / image_width;;
    auto pixel_delta_v= viewport_v / image_height;

    // 左下角像素的位置  相机在原点看向 z轴负方向
    auto viewport_upper_left = camera_center - vec3(0,0,focal_legth)-viewport_u*0.5-viewport_v*0.5;
    // 所以说之前算的都是像素的左上角的位置，这里再斜向下移动半个像素，就是像素中心的位置
    auto pixel00_loc = viewport_upper_left + 0.5*(pixel_delta_u+pixel_delta_v);

    // log
    std::ofstream output_file("sphere.ppm");
    output_file << "P3\n" << image_width << ' ' << image_height << "\n255\n";
    // render
    for (int j = 0; j < image_height; ++j) {

        std::cout << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush; 
        for (int i = 0; i < image_width; i++)
        {
            /* code */
            
            auto pixel_center = pixel00_loc + i * pixel_delta_u + j * pixel_delta_v;
            auto ray_direction = pixel_center - camera_center;
            ray r (camera_center,ray_direction);
            color pixel_color= ray_color(r,world);
            write_color(output_file, pixel_color);

        }
    }
    std::clog << "\rDone.\n";
}
